package developer.zyk.starter.controllers.knowledge;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import developer.zyk.ability.chat.ability.rag.RagHandleTemplate;
import developer.zyk.ability.chat.ability.rag.vector.VectorStoreManager;
import developer.zyk.ability.helper.ModelConfigHelper;
import developer.zyk.ability.knowledge.bo.OperateRecord;
import developer.zyk.ability.knowledge.common.KnowledgeTypeEnum;
import developer.zyk.ability.knowledge.common.KnowledgeUploadStatus;
import developer.zyk.ability.knowledge.dao.entity.ChatKnowledgeRecordDO;
import developer.zyk.ability.knowledge.param.ChatKnowledgeSearchParam;
import developer.zyk.ability.knowledge.param.ChatKnowledgeSubmitParam;
import developer.zyk.ability.knowledge.param.ChatKnowledgeTextParam;
import developer.zyk.ability.knowledge.param.KnowledgeEnableParam;
import developer.zyk.ability.knowledge.service.ChatKnowledgeService;
import developer.zyk.global.common.Result;
import developer.zyk.global.upload.FileUtil;
import developer.zyk.global.upload.dao.entity.ChatObjectRepositoryDO;
import developer.zyk.global.user.bo.UserInfo;
import developer.zyk.global.user.helper.UserInfoHelper;
import developer.zyk.global.util.AssertUtil;
import developer.zyk.starter.controllers.knowledge.vo.ChatKnowledgeVO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
 * @author zhangyongkang
 * @time 2025/5/13 19:45
 * @description
 */
@Slf4j
@RestController
@RequestMapping("knowledge/manage")
public class ChatKnowledgeManageController {
    @Resource
    private ChatKnowledgeService chatKnowledgeService;
    @Resource
    private RagHandleTemplate ragHandleTemplate;
    @Resource
    private VectorStoreManager vectorStoreManager;
    @Resource
    private TransactionTemplate transactionTemplate;


    @PostMapping("submit")
    public Result<List<Long>> submit(@RequestBody ChatKnowledgeSubmitParam chatKnowledgeSubmitParam) {
        if (ObjectUtil.isAllEmpty(
                chatKnowledgeSubmitParam.getDocumentUrl(),
                chatKnowledgeSubmitParam.getFileUrl(),
                chatKnowledgeSubmitParam.getFileList()
        )) {
            return Result.fail(501, "请选择数据！");
        }
        List<Long> recordIds = chatKnowledgeService.addRecord(chatKnowledgeSubmitParam, KnowledgeTypeEnum.UNSTRUCTURED);

        if (ModelConfigHelper.autoParse(() -> null)) {
            CompletableFuture.runAsync(() -> {
                parseDocument(recordIds, UserInfoHelper.getUserInfoById(chatKnowledgeSubmitParam.getUserId()));
            });
        }
        return Result.success(recordIds);
    }

    @PostMapping("saveOrUpdateText")
    public Result<Long> saveOrUpdateText(@RequestBody ChatKnowledgeTextParam chatKnowledgeTextParam) {
        Long recordId = chatKnowledgeService.addOrUpdateTextRecord(
                chatKnowledgeTextParam,
                KnowledgeTypeEnum.STRUCT
        );
        UserInfo userInfo = UserInfoHelper.getUserInfoById(chatKnowledgeTextParam.getUserId());
        if (ModelConfigHelper.autoParse(() -> null)) {
            CompletableFuture.runAsync(() -> {
                if (chatKnowledgeTextParam.getRecordId() != null) {//修改 先删除再解析
                    vectorStoreManager.removeByRecordIds(
                            List.of(chatKnowledgeTextParam.getRecordId())
                    );
                }
                ragHandleTemplate.handleKnowledge(recordId, userInfo);
            });
        }
        return Result.success(recordId);

    }

    private void parseDocument(List<Long> recordIds, UserInfo userInfo) {
        if (CollUtil.isEmpty(recordIds)) {
            return;
        }

        recordIds.stream().filter(Objects::nonNull)
                .forEach(recordId -> {
                    try {
                        ChatKnowledgeRecordDO record = chatKnowledgeService.getById(recordId);
                        ragHandleTemplate.handleKnowledge(
                                record.getId(),
                                userInfo
                        );
                    } catch (Throwable t) {
                        log.error("文档解析失败:{}", t.getMessage(), t);
                    }
                });
    }

    @PostMapping("datas")
    public Result<List<ChatKnowledgeVO>> datas(@RequestBody @Valid ChatKnowledgeSearchParam chatKnowledgeSearchParam) {
        AssertUtil.assertNonNull(chatKnowledgeSearchParam.getUserId(), "用户ID不为空");
        List<ChatKnowledgeRecordDO> datas = chatKnowledgeService.search(chatKnowledgeSearchParam);
        List<Long> fileIds = datas.stream()
                .map(ChatKnowledgeRecordDO::getFileId)
                .toList();
        Map<Long, ChatObjectRepositoryDO> fileMap = FileUtil.getFileMapByFileIs(fileIds);
        Map<Long, UserInfo> userInfoMap = UserInfoHelper.getUserInfoMapByIds(datas.stream().map(ChatKnowledgeRecordDO::getBelongUserId).toList());
        List<ChatKnowledgeVO> results = datas.stream()
                .map(a -> {
                    ChatObjectRepositoryDO fileInfo = fileMap.getOrDefault(a.getFileId(), new ChatObjectRepositoryDO());
                    ChatKnowledgeVO chatKnowledgeVO = new ChatKnowledgeVO();
                    chatKnowledgeVO.setId(a.getId());
                    chatKnowledgeVO.setFileName(fileInfo.getFileName());
                    chatKnowledgeVO.setUrl(fileInfo.getUrl());
                    chatKnowledgeVO.setPath(fileInfo.getPath());
                    chatKnowledgeVO.setFileId(fileInfo.getId());
                    chatKnowledgeVO.setModifyTime(a.getModifyTime());
                    Optional.of(userInfoMap)
                            .map(b -> b.get(a.getBelongUserId()))
                            .ifPresent(userInfo -> {
                                chatKnowledgeVO.setCreateBy(userInfo.getUserName());
                            });

                    chatKnowledgeVO.setEnable(a.getEnable());

                    chatKnowledgeVO.setStatus(a.getStatus());
                    chatKnowledgeVO.setStatusText(a.getStatusText());
                    List<OperateRecord> operateRecords = Optional.ofNullable(
                                    JSONUtil.toList(a.getRecord(), OperateRecord.class))
                            .orElse(new ArrayList<>()
                            );
                    chatKnowledgeVO.setOperateList(
                            operateRecords
                    );
                    chatKnowledgeVO.setTitle(a.getTitle());
                    chatKnowledgeVO.setContentPrefix(a.getContent());

                    //权限控制
                    chatKnowledgeVO.setPermission(ChatKnowledgeVO.Permission.of(
                                    true,
                                    false,
                                    KnowledgeUploadStatus.queryByCode(a.getStatus()).getEnableParse(),
                                    true
                            )
                    );
                    return chatKnowledgeVO;
                })
                .toList();
        return Result.success(results);
    }

    @PostMapping("enable")
    public Result<Boolean> enable(
            @RequestBody KnowledgeEnableParam knowledgeEnableParam
    ) {

        boolean b = chatKnowledgeService.updateEnableStatus(knowledgeEnableParam.getRecordId(),
                knowledgeEnableParam.getEnable());

        CompletableFuture.runAsync(() -> {
            Integer enable = knowledgeEnableParam.getEnable();
            Long recordId = knowledgeEnableParam.getRecordId();
            switch (enable) {
                case 0 -> {
                    vectorStoreManager.removeByRecordIds(
                            List.of(recordId)
                    );
                    log.info("移除知识库成功:{}", recordId);
                }
                case 1 -> {
                    vectorStoreManager.load(List.of(recordId));
                    log.info("加载知识库成功:{}", recordId);
                }
                default -> throw new UnsupportedOperationException("不支持的状态");
            }
        });
        return Result.success(b);
    }

    @PostMapping("delete/{id}")
    public Result<Boolean> delete(
            @PathVariable Long id
    ) {
        Boolean execute = transactionTemplate.execute((action) -> {
            vectorStoreManager.realDelete(List.of(id));
            return chatKnowledgeService.deleteById(id);
        });

        return Result.success(execute);
    }
}
